/****************************************************************************

 main-widget.cpp -

Copyright (C) Michael R Fisher <mfisher31@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 01222-1307 USA

****************************************************************************/

#include <iostream>
#include <map>

#include "plugin.hpp"
#include "main-widget.hpp"
#include "control-box.hpp"

using namespace std;
using namespace Gtk;

MainWidget::MainWidget(const char* ui_bundle)
: VBox(),header(false,4),c_box(),footer(false,4),
  m_ui_bundle(ui_bundle)
{
  string pic = m_ui_bundle + "/pixmaps/lv2_shaded_black.png";
  Glib::RefPtr<Gdk::Pixbuf> image = Gdk::Pixbuf::create_from_file(pic);

  Gtk::Image* img = manage( new Image(pic));
  img->set_size_request(50,-1);
  header.pack_start(*img,PACK_SHRINK);

/*  This portion = me figuring out cosmetics for where to put a "presets"
 * widget.
 *
  Gtk::Button *btn = manage( new Button("Default Program"));
  btn->set_size_request(-1, 25);

  Gtk::SpinButton *spin = manage( new SpinButton());
  spin->set_size_request(-1, 25);

  header.pack_end(*spin,PACK_SHRINK);
  header.pack_end(*btn,PACK_SHRINK);
*/

  //connections
  slot<void,string&,float> f = mem_fun(*this, &MainWidget::on_control_changed);
  c_box.signal_control_changed.connect(f);

  pack_start(header);
  pack_start(c_box);
  pack_start(footer);

}

void MainWidget::on_control_changed(string& symbol, float value) {
  uint32_t index = 999999;
  Plugin::miter_t it;

  // find the index for a symbol.
  for(it = p_symbol_map->begin(); it != p_symbol_map->end(); it++) {

    if(it->first == symbol) {
      index = it->second;
      signal_write_control(index,value);

      #ifndef NDEBUG
        cout << "index:" << index
            << " symbol:" << symbol
            << " value:" << value
            << endl;
      #endif

      break;
    }
  }
}

MainWidget::~MainWidget()
{

}

void MainWidget::add_control(Port& port) {

  m_adj_map[port.symbol] = c_box.add<HScale>(port);

}

void MainWidget::set_symbol_map(Plugin::map_t* map) {
  p_symbol_map = map;
}

void MainWidget::set_plugin_info(PluginInfo* info) {
  p_info = info;

  #ifndef NDEBUG
    cout << "\nMainWidget::set_plugin_info()\n";
    cout << p_info->name << endl;
    cout << p_info->author << endl;
    cout << p_info->license << endl;
    cout << p_info->docs << endl;
  #endif

    Label* n;
    Label* a;

    n = manage( new Label(p_info->name) );
    a = manage( new Label(p_info->author) );
    n->set_alignment(0.0, 0.5);

    header.pack_start(*n, PACK_SHRINK);
    footer.pack_end(*a,PACK_SHRINK);
}

// This is not currently used. please see control-box.hpp

Widget* MainWidget::create_control(Port& port) {
  Adjustment *adj;
  Label *lbl = manage( new Label(port.name));
  HScale *s = manage( new HScale());
  SpinButton *spin = manage( new  SpinButton());
  HBox *box = manage( new HBox(false, 15));

  adj = new Adjustment (port.default_value,
                        port.minimum_value, // double lower,
                        port.maximum_value, //double upper,
                        0.00001, //double step_increment=1,
                        1,       //double page_increment=10,
                        0);       //double page_size=0)

  s->set_draw_value(false);
  s->set_adjustment(*adj);
  s->set_size_request(150,-1);

  lbl->set_alignment(0,0.5);
  lbl->set_size_request(75,-1);

  spin->set_adjustment(*adj);
  spin->set_digits(2);

  m_adj_map[port.symbol] = adj;

  box->pack_start(*lbl,PACK_SHRINK);
  box->pack_start(*s);
  box->pack_start(*spin, PACK_SHRINK);


  return box;
}
